/*
 * @(#)SVGDrawingPanelSample.java
 * 
 * Copyright (c) 2009-2010 by the original authors of JHotDraw and all its
 * contributors. All rights reserved.
 * 
 * You may not use, copy or modify this file, except in compliance with the 
 * license agreement you entered into with the copyright holders. For details
 * see accompanying license terms.
 */
package org.jhotdraw.samples.mini;

import java.awt.Dimension;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import javax.swing.JFileChooser;
import javax.swing.JOptionPane;
import org.jhotdraw.draw.Drawing;
import org.jhotdraw.draw.io.InputFormat;
import org.jhotdraw.draw.io.OutputFormat;
import org.jhotdraw.gui.Worker;
import org.jhotdraw.gui.filechooser.ExtensionFileFilter;

/**
 * Example showing how to embed the {@link org.jhotdraw.samples.svg.SVGDrawingPanel} into an application
 * that does not make use of the JHotDraw application framework.
 * <p>
 * In this case, the application consists of a JFrame with a File menu.
 *
 * @author Werner Randelshofer
 * @version $Id: SVGDrawingPanelSample.java 718 2010-11-21 17:49:53Z rawcoder $
 */
public class SVGDrawingPanelSample extends javax.swing.JFrame {

    /** Holds the file chooser for opening a file. */
    private JFileChooser openChooser;
    /** Holds the file chooser for saving a file. */
    private JFileChooser saveChooser;
    /** Maps file filters to input formats, so that we can
     * determine the input format that the user selected for
     * opening a drawing.
     */
    private HashMap<javax.swing.filechooser.FileFilter, InputFormat> fileFilterInputFormatMap;
    /** Maps file filters to output formats, so that we can
     * determine the output format that the user selected for
     * opening a drawing.
     */
    private HashMap<javax.swing.filechooser.FileFilter, OutputFormat> fileFilterOutputFormatMap;
    /** Holds the currently opened file. */
    private File file;

    /** Creates new form SVGDrawingPanelSample */
    public SVGDrawingPanelSample() {
        initComponents();
        setSize(new Dimension(600, 400));
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        svgPanel = new org.jhotdraw.samples.svg.SVGDrawingPanel();
        menuBar = new javax.swing.JMenuBar();
        fileMenu = new javax.swing.JMenu();
        openMenuItem = new javax.swing.JMenuItem();
        saveAsMenuItem = new javax.swing.JMenuItem();

        FormListener formListener = new FormListener();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        getContentPane().add(svgPanel, java.awt.BorderLayout.CENTER);

        fileMenu.setText("File");

        openMenuItem.setText("Open...");
        openMenuItem.addActionListener(formListener);
        fileMenu.add(openMenuItem);

        saveAsMenuItem.setText("Save As...");
        saveAsMenuItem.addActionListener(formListener);
        fileMenu.add(saveAsMenuItem);

        menuBar.add(fileMenu);

        setJMenuBar(menuBar);

        pack();
    }

    // Code for dispatching events from components to event handlers.

    private class FormListener implements java.awt.event.ActionListener {
        FormListener() {}
        @Override
		public void actionPerformed(java.awt.event.ActionEvent evt) {
            if (evt.getSource() == openMenuItem) {
                SVGDrawingPanelSample.this.open(evt);
            }
            else if (evt.getSource() == saveAsMenuItem) {
                SVGDrawingPanelSample.this.saveAs(evt);
            }
        }
    }// </editor-fold>//GEN-END:initComponents

    /** Opens a drawing from a file. */
    private void open(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_open
        JFileChooser fc = getOpenChooser();
        if (file != null) {
            fc.setSelectedFile(file);
        }

        if (fc.showOpenDialog(this) == JFileChooser.APPROVE_OPTION) {
            svgPanel.setEnabled(false);
            final File selectedFile = fc.getSelectedFile();
            final InputFormat selectedFormat = fileFilterInputFormatMap.get(fc.getFileFilter());
            new Worker() {

                @Override
                protected Object construct() throws IOException {
                    svgPanel.read(selectedFile.toURI(), selectedFormat);
                    return null;
                }

                @Override
                protected void done(Object value) {
                    file = selectedFile;
                    setTitle(file.getName());
                }

                @Override
                protected void failed(Throwable error) {
                    error.printStackTrace();
                    JOptionPane.showMessageDialog(SVGDrawingPanelSample.this,
                            "<html><b>Couldn't open file \"" + selectedFile.getName() + "\"<br>" +
                            error.toString(), "Open File", JOptionPane.ERROR_MESSAGE);
                }

                @Override
                protected void finished() {
                    svgPanel.setEnabled(true);
                }
            }.start();
        }
    }//GEN-LAST:event_open

    /** Saves a drawing to a file. */
    private void saveAs(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_saveAs
        JFileChooser fc = getSaveChooser();
        if (file != null) {
            fc.setSelectedFile(file);
        }

        if (fc.showSaveDialog(this) == JFileChooser.APPROVE_OPTION) {
            svgPanel.setEnabled(false);
            final File selectedFile;
            if (fc.getFileFilter() instanceof ExtensionFileFilter) {
                selectedFile = ((ExtensionFileFilter) fc.getFileFilter()).makeAcceptable(fc.getSelectedFile());
            } else {
                selectedFile = fc.getSelectedFile();
            }
            final OutputFormat selectedFormat = fileFilterOutputFormatMap.get(fc.getFileFilter());
            new Worker() {

                @Override
                protected Object construct() throws IOException {
                    svgPanel.write(selectedFile.toURI(), selectedFormat);
                    return null;
                }

                @Override
                protected void done(Object value) {
                    file = selectedFile;
                    setTitle(file.getName());
                }

                @Override
                protected void failed(Throwable error) {
                    error.printStackTrace();
                    JOptionPane.showMessageDialog(SVGDrawingPanelSample.this,
                            "<html><b>Couldn't save to file \"" + selectedFile.getName() + "\"<br>" +
                            error.toString(), "Save As File", JOptionPane.ERROR_MESSAGE);
                }

                @Override
                protected void finished() {
                    svgPanel.setEnabled(true);
                }
            }.start();
        }
    }//GEN-LAST:event_saveAs

    /** Lazily creates a JFileChooser and returns it. */
    private JFileChooser getOpenChooser() {
        if (openChooser == null) {
            openChooser = new JFileChooser();
            Drawing d = svgPanel.getDrawing();
            fileFilterInputFormatMap = new HashMap<javax.swing.filechooser.FileFilter, InputFormat>();
            javax.swing.filechooser.FileFilter firstFF = null;
            for (InputFormat format : d.getInputFormats()) {
                javax.swing.filechooser.FileFilter ff = format.getFileFilter();
                if (firstFF == null) {
                    firstFF = ff;
                }
                fileFilterInputFormatMap.put(ff, format);
                openChooser.addChoosableFileFilter(ff);
            }
            openChooser.setFileFilter(firstFF);
            openChooser.addPropertyChangeListener(new PropertyChangeListener() {

                @Override
                public void propertyChange(PropertyChangeEvent evt) {
                    if (evt.getPropertyName().equals("fileFilterChanged")) {
                        InputFormat inputFormat = fileFilterInputFormatMap.get(evt.getNewValue());
                        openChooser.setAccessory((inputFormat == null) ? null : inputFormat.getInputFormatAccessory());
                    }
                }
            });
        }
        return openChooser;
    }

    /** Lazily creates a JFileChooser and returns it. */
    private JFileChooser getSaveChooser() {
        if (saveChooser == null) {
            saveChooser = new JFileChooser();
            Drawing d = svgPanel.getDrawing();
            fileFilterOutputFormatMap = new HashMap<javax.swing.filechooser.FileFilter, OutputFormat>();
            javax.swing.filechooser.FileFilter firstFF = null;
            for (OutputFormat format : d.getOutputFormats()) {
                javax.swing.filechooser.FileFilter ff = format.getFileFilter();
                if (firstFF == null) {
                    firstFF = ff;
                }
                fileFilterOutputFormatMap.put(ff, format);
                saveChooser.addChoosableFileFilter(ff);
            }
            saveChooser.setFileFilter(firstFF);
            saveChooser.addPropertyChangeListener(new PropertyChangeListener() {

                @Override
                public void propertyChange(PropertyChangeEvent evt) {
                    if (evt.getPropertyName().equals("fileFilterChanged")) {
                        OutputFormat outputFormat = fileFilterOutputFormatMap.get(evt.getNewValue());
                        saveChooser.setAccessory((outputFormat == null) ? null : outputFormat.getOutputFormatAccessory());
                    }
                }
            });
        }
        return saveChooser;
    }

    /**
     * @param args the command line arguments
     */
    public static void main(String args[]) {
        java.awt.EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                new SVGDrawingPanelSample().setVisible(true);
            }
        });
    }
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JMenu fileMenu;
    private javax.swing.JMenuBar menuBar;
    private javax.swing.JMenuItem openMenuItem;
    private javax.swing.JMenuItem saveAsMenuItem;
    private org.jhotdraw.samples.svg.SVGDrawingPanel svgPanel;
    // End of variables declaration//GEN-END:variables
}
